package com.wei.czz.framework.admin.manager;

import com.wei.czz.common.dto.admin.deptRole.DeptRoleDto;
import com.wei.czz.common.enums.CommonEnum;
import com.wei.czz.common.enums.ResultEnum;
import com.wei.czz.common.enums.rabbitMQ.MqEnum;
import com.wei.czz.common.exception.CzzException;
import com.wei.czz.common.po.UserPo;
import com.wei.czz.common.po.admin.deptRole.DeptRolePagePo;
import com.wei.czz.common.tool.PageDto;
import com.wei.czz.common.utils.CopyUtils;
import com.wei.czz.common.utils.SecurityUtils;
import com.wei.czz.common.vo.admin.deptRole.DeptRoleFormVo;
import com.wei.czz.common.vo.admin.deptRole.DeptRoleVo;
import com.wei.czz.common.vo.common.UpdateStatusVo;
import com.wei.czz.framework.admin.entity.DeptRoleEntity;
import com.wei.czz.framework.admin.service.DeptRoleService;
import com.wei.czz.framework.admin.service.RoleService;
import com.wei.czz.framework.common.helper.RabbitHelper;
import com.wei.czz.framework.rabbitMQ.message.dept.DeptRoleMessage;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wyw
 * date: 2024-04-29 12:03:46
 * className: DeptRoleManager
 * version: 1.0
 * description:
 */
@Component
@AllArgsConstructor
public class DeptRoleManager {

    private static final Logger log = LoggerFactory.getLogger(DeptRoleManager.class);

    private final DeptRoleService deptRoleService;

    private final RoleService roleService;

    private final RabbitHelper rabbitHelper;

    public void save(DeptRoleVo deptRoleVo) {
        // 获取操作对象
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        /*
            判断部门是否可以关联角色
         */
        List<Long> deptIdList = Collections.singletonList(deptRoleVo.getDeptId());
        List<DeptRoleEntity> deptRoleList = deptRoleService.findDeptRoleList(deptIdList);
        boolean bool = deptRoleList.stream()
                .filter(deptRole -> !deptRole.getId().equals(deptRoleVo.getId()))
                .anyMatch(deptRole -> deptRole.getRoleId().equals(deptRoleVo.getRoleId()));
        if (bool) {
            throw new CzzException(ResultEnum.REQUEST_FAIL.getCode(), "部门已关联该角色，无需重复关联");
        }

        /*
            保存部门与角色对象
         */
        DeptRoleEntity deptRole = new DeptRoleEntity();
        deptRole.setDeptId(deptRoleVo.getDeptId())
                .setRoleId(deptRoleVo.getRoleId())
                .setUseRange(deptRoleVo.getUseRange())
                .setUseLeader(deptRoleVo.getUseLeader())
                .setStatus(CommonEnum.ZERO.getValue())
                .setDeleteStatus(CommonEnum.ZERO.getValue())
                .setUpdateTime(date)
                .setUpdateUser(StringUtils.EMPTY)
                .setUpdateUserId(CommonEnum.ZERO.getLongValue())
                .setCreateTime(date)
                .setCreateUser(userPo.getUsername())
                .setCreateUserId(userPo.getUserId());
        deptRoleService.saveOrEdit(deptRole);

        // 发送mq消息
        DeptRoleMessage deptRoleMessage = new DeptRoleMessage();
        deptRoleMessage.setDeptId(deptRoleVo.getDeptId())
                .setRoleIdList(Collections.singletonList(deptRoleVo.getRoleId()));
        rabbitHelper.send(MqEnum.DEPT_ROLE, deptRoleMessage);
    }

    public PageDto<DeptRoleDto> getPageList(DeptRoleFormVo deptRoleFormVo) {
        /*
            分页获取部门关联角色
         */
        PageDto<DeptRolePagePo> pageDto = roleService.getDeptRolePageList(deptRoleFormVo);
        if (pageDto.isEmpty()) {
            return pageDto.rebuild();
        }

        List<DeptRolePagePo> roleList = pageDto.getList();

        String deptId = deptRoleFormVo.getDeptId().toString();

        // 列表映射
        List<DeptRoleDto> deptRoleDtoList = CopyUtils.mapList(roleList, DeptRoleDto.class, (role, deptRole) -> {
            deptRole.setDeptId(deptId);
        });

        // 封装返回
        return pageDto.rebuild(deptRoleDtoList);
    }

    public void update(DeptRoleVo deptRoleVo) {
        // 获取操作对象
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        /*
            保存部门与角色对象
         */
        DeptRoleEntity updateDeptRole = new DeptRoleEntity();
        updateDeptRole.setId(deptRoleVo.getId())
                .setUseRange(deptRoleVo.getUseRange())
                .setUseLeader(deptRoleVo.getUseLeader())
                .setUpdateTime(date)
                .setUpdateUser(userPo.getUsername())
                .setUpdateUserId(userPo.getUserId());
        deptRoleService.saveOrEdit(updateDeptRole);

        // 发送mq消息
        DeptRoleMessage deptRoleMessage = new DeptRoleMessage();
        deptRoleMessage.setDeptId(deptRoleVo.getDeptId())
                .setRoleIdList(Collections.singletonList(deptRoleVo.getRoleId()));
        rabbitHelper.send(MqEnum.DEPT_ROLE, deptRoleMessage);

    }

    public void updateStatus(UpdateStatusVo updateStatusVo) {
        // 获取请求用户
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        /*
            获取部门关联角色列表
         */
        List<DeptRoleEntity> deptRoleList = deptRoleService.getList(updateStatusVo.getIdList());
        if (deptRoleList.isEmpty()) {
            log.info("【更新状态】数据已被删除");
            throw new CzzException(ResultEnum.DATA_DUPLICATION);
        }

        List<DeptRoleEntity> updateDeptRoleList = new ArrayList<>();

        Map<Long, List<Long>> deptRoleMap = deptRoleList.stream()
                .peek(deptRole -> {
                    DeptRoleEntity updateDeptRole = new DeptRoleEntity();
                    updateDeptRole.setId(deptRole.getId())
                                    .setStatus(updateStatusVo.getStatus())
                                    .setUpdateTime(date)
                                    .setUpdateUser(userPo.getUsername())
                                    .setUpdateUserId(userPo.getUserId());
                    updateDeptRoleList.add(updateDeptRole);
                })
                .collect(
                    Collectors.groupingBy(
                            DeptRoleEntity::getDeptId,
                            Collectors.mapping(DeptRoleEntity::getRoleId, Collectors.toList())
                    )
        );

        /*
            批量更新部门与角色
         */
        deptRoleService.batchUpdate(updateDeptRoleList);

        /*
            发送mq消息
         */
        for (Map.Entry<Long, List<Long>> entry : deptRoleMap.entrySet()) {
            Long deptId = entry.getKey();
            List<Long> roleIdList = entry.getValue();
            log.info("【更新状态】发送mq消息更新部门用户关联角色。deptId={} roleIdList={}", deptId, roleIdList);
            DeptRoleMessage deptRoleMessage = new DeptRoleMessage();
            deptRoleMessage.setDeptId(deptId)
                    .setRoleIdList(roleIdList);
            rabbitHelper.send(MqEnum.DEPT_ROLE, deptRoleMessage);
        }
    }

    public void batchDelete(List<Long> idList) {

        /*
            获取部门关联角色列表
         */
        List<DeptRoleEntity> deptRoleList = deptRoleService.getList(idList);
        if (deptRoleList.isEmpty()) {
            log.info("【删除】数据已被删除");
            throw new CzzException(ResultEnum.DATA_DUPLICATION);
        }

        Map<Long, List<Long>> deptRoleMap = deptRoleList.stream().collect(
                Collectors.groupingBy(
                        DeptRoleEntity::getDeptId,
                        Collectors.mapping(DeptRoleEntity::getRoleId, Collectors.toList())
                )
        );

        /*
            删除部门关联角色
         */
        deptRoleService.deleteDeptRole(idList, null, null);

        /*
            发送mq消息
         */
        for (Map.Entry<Long, List<Long>> entry : deptRoleMap.entrySet()) {
            Long deptId = entry.getKey();
            List<Long> roleIdList = entry.getValue();
            log.info("【删除】发送mq消息更新部门用户关联角色。deptId={} roleIdList={}", deptId, roleIdList);
            DeptRoleMessage deptRoleMessage = new DeptRoleMessage();
            deptRoleMessage.setDeptId(deptId)
                    .setRoleIdList(roleIdList);
            rabbitHelper.send(MqEnum.DEPT_ROLE, deptRoleMessage);
        }
    }
}
